package com.ehotting.edsta.circuitDesign.gen;

import com.ehotting.edsta.circuitDesign.uitls.CircuitThreadContext;
import lombok.SneakyThrows;
import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.*;

public abstract class MultiThreadQueueHelper<T> {

    private CircuitThreadContext circuitThreadContext;

    private BlockingQueue<String> blockingQueue;


    public void execute(List<T> list) throws InterruptedException {
        blockingQueue = new LinkedBlockingDeque<>();

        int availableProcessors = Runtime.getRuntime().availableProcessors();

        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(availableProcessors + 1); // 设置核心线程数
        taskExecutor.setMaxPoolSize(list.size() + availableProcessors); // 设置最大线程数
        taskExecutor.setQueueCapacity(list.size() + availableProcessors); // 设置队列容量
        taskExecutor.setThreadNamePrefix("MultiThreadQueueThread-"); // 设置线程名前缀
        taskExecutor.initialize();

        for (T t : list){
            offer();
            taskExecutor.execute(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    try {
                        Thread.sleep(500);
                        task(t);
                        Thread.sleep(500);
                    }catch (Exception e) {
                        poll();
                        throw e;
                    }finally {
                        poll();
                    }
                }
            });

        }


        while (true){
            if(!circuitThreadContext.isActive()){
                taskExecutor.shutdown();
            }
            if (blockingQueue.size() == 0){
                break;
            }
        }

        taskExecutor.shutdown();

    }

    public abstract void task(T t);

    public void offer() throws InterruptedException {
        blockingQueue.put("1");
    }

    public void poll() throws InterruptedException {
        blockingQueue.take();
    }

    public void setCircuitThreadContext(CircuitThreadContext circuitThreadContext) {
        this.circuitThreadContext = circuitThreadContext;
    }
}
